#include "covert.h"

/**
 * \brief 16进制字符转16进制
 * \param [in] c 要处理的字符
 * \return hex 最终值
 * \example '5' -> 0x5   'b'-> 0xb
 */
uchr8_t char_to_hex(chr8_t c)
{
    switch (c) {
        case '0' ... '9':
            return c - '0';
        case 'a' ... 'f':
            return c - 'a' + 10;
        case 'A' ... 'F':
            return c - 'A' + 10;
        default:
            return 0xFF;
    }
}

/**
 * \brief 16进制转16进制字符
 * \param [in] h 要处理的数字
 * \return hex 最终值
 * \example 0x5 -> '5'  0xb -> 'B'
 */
chr8_t hex_to_char(uchr8_t h)
{
    if (h <= 9)
        return h + '0';
    else if ((h >= 10) && (h <= 15))
        return h + ('A' - 10);
    else
        return '\0';
}

/**
 * \brief 16进制字符串转成16进制整型
 * \param [in] str 要处理的字符串
 * \return hex 最终值
 * \example "12" -> 0x12   "ab" -> 0xab
 */
int32_t str_to_hex(chr8_t *str)
{
    int32_t hex = 0;

    while (*str && IS_HEX(*str)) {
        hex = (hex << 4) + char_to_hex(*str++);
    }

    return hex;
}

/**
 * \brief 10进制字符串转成10进制整型
 * \param [in] str 要处理的字符串
 * \return digit 最终值
 * \example "12" -> 0x0b   "ab" -> 0x0(不支持返回0)
 */
int32_t str_to_digit(chr8_t *str)
{
    int32_t digit = 0;

    if (str == NULL || strlen(str) == 0) {
        return 0; // 字符串为空，返回0
    }

    while (*str && IS_DIGIT(*str)) {
        digit = (digit * 10 + (*str - '0'));
        str++;
    }

    return digit;
}

/**
 * \brief 将十进制数据转换成BCD码（二进制格式的数字码）
 * \param [in] dec 要转换的十进制数据
 *        [in] buf 缓存区
 *        [in] buflen 缓存长度
 * \return dec_bytes 返回十进制位数
 */
int32_t dec2bcd(int32_t dec, uchr8_t *buf, usht16_t buflen)
{
    int32_t i;
    int32_t temp;
    uchr8_t dec_bytes;

    temp = dec;
    dec_bytes = 1;
    while (temp / 100) {
        dec_bytes++;
        temp /= 100;
    }
    if (dec_bytes > buflen) {
        return 0;
    }

    for (i = dec_bytes - 1; i >= 0; i--) {
        temp = dec % 100;
        buf[i] = BIN2BCD(temp);
        dec /= 100;
    }

    return dec_bytes;
}

int32_t bcd2dec(uchr8_t *bcd, usht16_t bcdlen)
{
    uint32_t factor;
    usht16_t len;
    int32_t dec;

    factor = 1;
    len = bcdlen;
    while (len-- > 1) {
        factor *= 100;
    }

    dec = 0;
    while (bcdlen--) {
        dec += BCD2BIN(*bcd) * factor;
        factor /= 100;
        bcd++;
    }
    return dec;
}

/**
 * \brief 将十进制数据转换成字符串数据
 * \param [in] dec 要转换的十进制数据
 *        [in] buf 缓存区
 *        [in] buflen 缓存长度
 * \return dec_bytes 返回十进制位数
 */
int32_t dec2ascii(int32_t dec, uchr8_t *buf, usht16_t buflen)
{
    int32_t i;
    int32_t temp;
    uchr8_t dec_bytes;

    temp = dec;
    dec_bytes = 1;
    while (temp / 10) {
        dec_bytes++;
        temp /= 10;
    }
    if (dec_bytes > buflen) {
        return 0;
    }
    // 通过取模运算将每一位十进制数转换成字符存储在缓冲区中
    for (i = dec_bytes - 1; i >= 0; i--) {
        temp = dec % 10;
        buf[i] = char_to_hex(temp & 0x0F);
        dec /= 10;
    }

    return dec_bytes;
}

/**
 * \brief 判断字符串是不是浮点数
 * \param [in] str 要判断的字符串
 * \return
 * USRTRUE  是浮点数
 * USRFALSE 不是浮点数
 */
usrbool str_isfloat(chr8_t *str)
{
    for (int32_t i = 0; str[i] != '\0'; i++) {
        if (!IS_FLOAT(str[i])) {
            return USRFALSE;
        }
    }

    return USRTRUE;
}

/**
 * \brief 判断字符串是不是16进制
 * \param [in] str 要判断的字符串
 * \return
 * USRTRUE  是16进制
 * USRFALSE 不是16进制
 */
usrbool str_ishex(chr8_t *str)
{
    for (int32_t i = 0; str[i] != '\0'; i++) {
        if (!IS_HEX(str[i])) {
            return USRFALSE;
        }
    }
    return USRTRUE;
}

/**
 * \brief 计算10的N次方
 * \param [in] n 对应的次方数
 * \return factor 最终值
 * \example 10**3 -> 1000
 */
uint32_t calc_10nth(uint32_t n)
{
    uint32_t i, factor = 1;

    for (i = 0; i < n; i++) {
        factor *= 10;
    }
    return factor;
}
